package servlet;

import entity.Category;
import entity.Item;
import entity.Wish;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import session.CategoryFacadeRemote;
import session.EbayRequestHandlerRemote;
import session.MailUtilRemote;
import session.UtenteFacadeRemote;
import session.WishFacadeRemote;
import static servlet.ServletUtil.*;

/**
 * Questa servlet si occupa di gestire la wishlist dell'utente.
 *
 * @author Rachid Ouchary, Fabio Strocco, Max Passaghe, Marco Tansini.
 */
@WebServlet(name="GestoreWishList", urlPatterns={"/GestoreWishList"})
public class GestoreWishList extends HttpServlet {
    @EJB
    private CategoryFacadeRemote categoryFacade;
    @EJB
    private MailUtilRemote mailUtil;
    @EJB
    private EbayRequestHandlerRemote ebayRequestHandler;
    @EJB
    private WishFacadeRemote wishFacade;
    @EJB
    private UtenteFacadeRemote utenteFacade;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String operation = getOperation(request);

        if (operation.equals(ACTION_AGGIUNGI_DESIDERIO)) {
            aggiungiDesiderio(request, response,
                    Long.parseLong(request.getParameter(PARAM_ITEM_ID)),
                    Integer.parseInt(request.getParameter(PARAM_PRIORITY)),
                    Integer.parseInt(request.getParameter(PARAM_VOTO)));
        } else if (operation.equals(ACTION_CREA_DESIDERIO)) {
            creaDesiderio(request, response,
                    Long.parseLong(request.getParameter(PARAM_MAIN_CATEGORY)),
                    Long.parseLong(request.getParameter(PARAM_SUB_CATEGORY)),
                    request.getParameter(PARAM_DESCRIZIONE),
                    Integer.parseInt(request.getParameter(PARAM_PRIORITY)),
                    Integer.parseInt(request.getParameter(PARAM_VOTO)));
        } else if(operation.equals(ACTION_VISUALIZZA_WISHLIST)) {
            visualizzaWishList(request, response, request.getParameter(PARAM_USERNAME_AMICO));
        } else if(operation.equals(ACTION_MODIFICA_DESIDERIO)) {
            modificaDesiderio(request, response,
                              Long.parseLong(request.getParameter(PARAM_WISH_ID)),
                              Integer.parseInt(request.getParameter(PARAM_PRIORITY)),
                              Integer.parseInt(request.getParameter(PARAM_VOTO)));
        } else if(operation.equals(ACTION_PRENOTA)) {
            prenota(request, response, Long.parseLong(request.getParameter(PARAM_WISH_ID)));
        } else if(operation.equals(ACTION_GET_CREA_DESIDERIO)) {
            getCreaDesiderio(request, response);
        }
    }

    // <editor-fold defaultstate="collapsed" desc="Eventi gestiti dal controller">
    /*
     * Aggiunge un desiderio all'utente.
     */
    private void aggiungiDesiderio(HttpServletRequest request, HttpServletResponse response,
                                   Long item_id, Integer priority,
                                   Integer voto) throws IOException, ServletException {
        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession();
        String username = (String) session.getAttribute(SESSION_UTENTE);
        if(!utenteFacade.aggiungiDesiderio(username, item_id, priority, voto)) {
            request.setAttribute(PARAM_MESSAGE, "Hai gi&agrave espresso questo desiderio.");
            request.getRequestDispatcher("Message.jsp").forward(request, response);
            return;
        }

        String user = request.getParameter(PARAM_WISHLISTOWNER);
        request.setAttribute(PARAM_MESSAGE, "Il desiderio &egrave stato aggiunto con successo " +
                                            "nella tua wishlist." +"<p><a href=\"MainDispatcher?operation=" + ACTION_VISUALIZZA_WISHLIST +
                                            "&" + PARAM_USERNAME_AMICO + "=" + user +
                                            "\">Torna alla wishlist di " + user + "</a><p/>");
        request.getRequestDispatcher("Message.jsp").forward(request, response);
    }

    /*
     * Crea un nuovo oggetto, e lo aggiunge all'utente come desiderio.
     */
    private void creaDesiderio(HttpServletRequest request, HttpServletResponse response,
                               Long mainCategoryId, Long subCategoryId, String descrizione,
                               Integer proiority, Integer voto)
                                          throws IOException, ServletException {

        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession();
        String username = (String) session.getAttribute(SESSION_UTENTE);

        Long categoryId = (subCategoryId == -1 ? mainCategoryId : subCategoryId);
        if(!utenteFacade.creaDesiderio(username, categoryId, descrizione,
                    proiority, voto)) {
            request.setAttribute(PARAM_MESSAGE, "Hai gi&agrave espresso questo desiderio.");
            request.getRequestDispatcher("Message.jsp").forward(request, response);
            return;
        }
        visualizzaWishList(request, response);
    }

    private void visualizzaWishList(HttpServletRequest request, HttpServletResponse response, String username) throws ServletException, IOException {
        HttpSession session = request.getSession();
        String current = (String) session.getAttribute(SESSION_UTENTE);

        if(username == null) {
            username = current;
        }
        
        request.setAttribute(PARAM_IS_USER_WISHLIST, username.equals(current));

        Collection<Wish> wishList = utenteFacade.getOrderedUserWishList(username);
        request.setAttribute(PARAM_WISHLIST, wishList);

        Map<Long, String> resultList = new HashMap<Long, String>();
        for(Wish wish : wishList) {
            Item item = wish.getItem();
            if(!resultList.containsKey(item.getId()))
                resultList.put(item.getId(),
                               ebayRequestHandler.request(item.getCategoria() , item.getDescrizione()));
        }
        request.setAttribute(PARAM_EBAY_RESULTS, resultList);
        request.getRequestDispatcher("Home.jsp").forward(request, response);
    }

    private void visualizzaWishList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        visualizzaWishList(request, response, null);
    }

    private void modificaDesiderio(HttpServletRequest request, HttpServletResponse response,
                                   Long wish_id, Integer priority, Integer voto) throws ServletException, IOException {
        HttpSession session = request.getSession();
        Wish wish = wishFacade.find(wish_id);
        wishFacade.modificaDesiderio(wish, priority, voto);
        visualizzaWishList(request, response);
    }

    private void prenota(HttpServletRequest request, HttpServletResponse response,
                         Long wish_id) throws ServletException, IOException {
        Wish wish = wishFacade.find(wish_id);
        String user = wish.getUtente().getUsername();
        wishFacade.prenota(wish);

        mailUtil.sendPrenotazioneMail(wish);
        String message ="<p>&Egrave stato inviato un messaggio di notifica di prenotazione all'utente " +
                        user + "</p>" +
                        "<p><a href=\"MainDispatcher?operation=" + ACTION_VISUALIZZA_WISHLIST +
                        "&" + PARAM_USERNAME_AMICO + "=" + user +
                        "\">Torna alla wishlist di " + user + "</a><p/>";
        request.setAttribute(PARAM_MESSAGE, message);
        request.setAttribute("operation", ACTION_MESSAGE);
        request.getRequestDispatcher("MainDispatcher").forward(request, response);
        //visualizzaWishList(request, response);
    }

    private void getCreaDesiderio(HttpServletRequest request, HttpServletResponse response) 
                                                          throws ServletException, IOException {
        Collection<Category> categoryList = categoryFacade.findMainCategories();
        request.setAttribute(PARAM_CATEGORY_LIST, categoryList);
        request.getRequestDispatcher("CreaDesiderio.jsp").forward(request, response);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}
